package ldk.app.kotlinweibo.apis

import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import ldk.app.kotlinweibo.apis.beans.BaseResponse
import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.internal.http.HttpHeaders
import okio.Buffer
import java.io.EOFException
import java.nio.charset.Charset

/**
 * Created by ke on 17-6-28.
 */
class APIInterceptor(gson: Gson): Interceptor{
    private val mGson = gson
    companion object{
        val UTF8 = Charset.forName("UTF-8")
    }

    override fun intercept(chain: Interceptor.Chain?): Response {
        val response = chain!!.proceed(chain.request())
        val responseBody = response.body()!!
        val contentLength = responseBody.contentLength()

        if (HttpHeaders.hasBody(response)){
            val source = responseBody.source()
            // request all body
            source.request(Long.MAX_VALUE)
            val buffer = source.buffer()
            var charset = UTF8
            val mediaType = responseBody.contentType()
            if (mediaType != null){
                charset = mediaType.charset(UTF8)
            }

            if (isPlaintext(buffer) && contentLength != 0L){
                val bodyString = buffer.clone().readString(charset)
                try {
                    val baseResponse = mGson.fromJson<BaseResponse>(bodyString, BaseResponse::class.java)
                    if (baseResponse!!.hasError()){
                        throw baseResponse
                    }
                }catch (e: JsonSyntaxException){

                }
            }
        }
        return response
    }

    /**
     * Returns true if the body in question probably contains human readable text. Uses a small sample
     * of code points to detect unicode control characters commonly used in binary file signatures.
     *
     * copy from HttpLoginInterceptor, and convert to kotlin by idea.
     */
    internal fun isPlaintext(buffer: Buffer): Boolean {
        try {
            val prefix = Buffer()
            val byteCount = if (buffer.size() < 64) buffer.size() else 64
            buffer.copyTo(prefix, 0, byteCount)
            for (i in 0..15) {
                if (prefix.exhausted()) {
                    break
                }
                val codePoint = prefix.readUtf8CodePoint()
                if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
                    return false
                }
            }
            return true
        } catch (e: EOFException) {
            return false // Truncated UTF-8 sequence.
        }

    }
}